package org.example.Service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.Http;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.example.Domain.ParamBuilder;
import org.example.Domain.SingleWord;
import org.example.Entity.Comment;
import org.example.Entity.LearnHistory;
import org.example.Entity.Word;
import org.example.Domain.WordAndExample;
import org.example.Dto.WordBookDTO;
import org.example.Entity.WordBook;
import org.example.Listener.SpeechAssessmentListener;
import org.example.Mapper.CommentMapper;
import org.example.Mapper.LearnHistoryMapper;
import org.example.Mapper.WordBookMapper;
import org.example.Mapper.WordMapper;
import org.example.Service.WordService;
import org.example.Utils.AuthUtil;
import org.example.Utils.HttpUtil;
import org.example.Vo.R;
import org.example.Vo.SearchWordVO;
import org.example.Vo.WordScoreVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class WordServiceImpl extends ServiceImpl<WordMapper, Word> implements WordService {

    private static final String appId = "3c591f62";
    private static final String apiKey = "14a25fc24a288e7c358a0e795275aa57";
    private static final String apiSecret = "Y2M2YWU0N2QzOGE0ODcyMmY3ODgzMWY2";

    @Autowired
    private WordMapper wordMapper;

    @Autowired
    private HttpUtil httpUtil;

    @Autowired
    private LearnHistoryMapper learnHistoryMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private WordBookMapper wordBookMapper;

    @Override
    public R search(String word) throws IOException {
        LambdaQueryWrapper<Word> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Word::getWord,word);
        List<Word> list = this.list(wrapper);
        Word targetWord = list.get(0);
        SearchWordVO searchWordVO = new SearchWordVO();
        searchWordVO.setWord(targetWord.getWord());
        searchWordVO.setPron(targetWord.getPron());
        searchWordVO.setDefinition(targetWord.getDefinition());
        List<WordAndExample> wordAndExamples = new ArrayList<>();
        String result = HttpUtil.sendGet("https://api.dictionaryapi.dev/api/v2/entries/en/", word);
        // 转化为json
        JSONArray jsonArray = JSON.parseArray(result);
        JSONObject jsonObject = jsonArray.getJSONObject(0);
        JSONArray meanings = jsonObject.getJSONArray("meanings");
        for ( int i = 0; i < meanings.size(); i++ ) {
            WordAndExample wordAndExample = new WordAndExample();
            JSONObject meaning = meanings.getJSONObject(i);
            String patOfSpeech = meaning.getString("partOfSpeech");
            wordAndExample.setType(patOfSpeech);
            ArrayList<String> examples = new ArrayList<>();
            JSONArray definitions = meaning.getJSONArray("definitions");
            for ( int j = 0; j < definitions.size(); j++ ) {
                String example = definitions.getJSONObject(j).getString("example");
                if ( Objects.nonNull(example) ) {
                    examples.add(example);
                }
            }
            wordAndExample.setSentence(examples);
            wordAndExamples.add(wordAndExample);
        }
        searchWordVO.setExamples(wordAndExamples);
        return R.ok(searchWordVO);
    }

    @Override
    public R speechAssessment(MultipartFile file, String text) throws Exception {
        WordScoreVO wordScoreVO = new WordScoreVO();
        wordScoreVO.setText(text);
        String hostUrl = "https://ise-api.xfyun.cn/v2/open-ise";
        String category = "read_word";
        text = "[word]\n" + text;
        System.out.println(text);
        String authUrl = AuthUtil.getAuthUrl(hostUrl,apiKey,apiSecret,"GET").replace("http://", "ws://").replace("https://", "wss://");//将url中的 schema http://和https://分别替换为ws:// 和 wss://;
        OkHttpClient client = new OkHttpClient.Builder().build();
        Request request = new Request.Builder().url(authUrl).build();
        String params = buildSpeechAssessmentRequest(text,category);
        StringBuilder answer = new StringBuilder();
        SpeechAssessmentListener listener = new SpeechAssessmentListener(file,params,answer);
        client.newWebSocket(request, listener);
        while ( !listener.getWsCloseFlag() ) {
            Thread.sleep(100);
        }
        System.out.println(answer);
        // 加载xml
        Document document = DocumentHelper.parseText(answer.toString());
        // 获取根节点
        Element root = document.getRootElement();
        Element readWord = root.element("read_word").element("rec_paper").element("read_word").element("sentence").element("word");
        wordScoreVO.setStandardScore(0);
        wordScoreVO.setAccuracyScore(0);
        wordScoreVO.setFluencyScore(0);
        wordScoreVO.setIntegrityScore(0);
        wordScoreVO.setTotalScore(Double.parseDouble(readWord.attributeValue("total_score")));
        return R.ok(wordScoreVO);
    }

    @Override
    public R insertWordByWordBook(WordBookDTO wordBookDTO,Integer type) {
        List<SingleWord> wordBook = wordBookDTO.getWordBook();
        for (SingleWord singleWord : wordBook) {
            System.out.println(singleWord.getContent());
            String word = singleWord.getContent();
            String pron = singleWord.getPron();
            String definition = singleWord.getDefinition();
            if (!word.isEmpty()) {
                Word wordEntity = new Word();
                wordEntity.setWord(word);
                wordEntity.setPron(pron);
                wordEntity.setDefinition(definition);
                wordEntity.setType(type);
                this.save(wordEntity);
            }
        }
        return R.ok();
    }

    @Override
    public R getRandomWord() {
        Integer len = wordMapper.getWordTableLen();
        int index = (int) (Math.random() * len);
        LambdaQueryWrapper<Word> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Word::getId, index);
        return R.ok(wordMapper.selectOne(wrapper));
    }

    @Override
    public R getLearnDetail(String username) {
        Integer userId = httpUtil.getUserId(username);
        LambdaQueryWrapper<LearnHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LearnHistory::getUserId, userId);
        List<LearnHistory> learnHistories = learnHistoryMapper.selectList(wrapper);
        // 根据learnHistory的type去重
        Integer storyCount = (int) learnHistories.stream().map(LearnHistory::getType).distinct().count();
        LambdaQueryWrapper<WordBook> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(WordBook::getUserId, userId);
        List<WordBook> wordBooks = wordBookMapper.selectList(wrapper1);
        // 找到所有WordBook是1的
        Integer knowWord = (int) wordBooks.stream().filter(wordBook -> wordBook.getBlur() == 0).count();
        Integer blurWord = (int) wordBooks.stream().filter(wordBook -> wordBook.getBlur() == 1).count();
        LambdaQueryWrapper<Comment> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(Comment::getUserId, userId);
        Integer commentCount = commentMapper.selectList(wrapper2).size();
        List<Integer> countList = new ArrayList<>();
        countList.add(knowWord);
        countList.add(blurWord);
        countList.add(storyCount);
        countList.add(commentCount);
        return R.ok(countList);
    }

    private String buildSpeechAssessmentRequest(String text,String category) {
        ParamBuilder p = new ParamBuilder();
        p.add("common", new ParamBuilder()
                        .add("app_id", appId)
                )
                .add("business", new ParamBuilder()
                        .add("category", category)
                        .add("rstcd", "utf8")
                        .add("sub","ise")
                        .add("ent","en_vip") // 评测语言选择英文
                        .add("tte", "utf-8")
                        .add("cmd", "ssb")
                        .add("auf", "audio/L16;rate=16000")
                        .add("aue", "lame") // 上传文件为mp3 选择使用lame接收
                        //评测文本(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF })+text)
                        .add("text",'\uFEFF'+text)//Base64.getEncoder().encodeToString(text.getBytes())
                ).add("data", new ParamBuilder()
                        .add("status", 0)
                        .add("data", ""));
        //System.err.println(p.toString());
        return p.toString();
    }

}
